package bo.edu.umss.jaba.hashtable;
 
import bo.edu.umss.jaba.node.* ;
import bo.edu.umss.jaba.analysis.* ;
import java.lang.System;
import java.io.*;

import java.util.List;
import java.util.LinkedList;
import java.util.Iterator;
import java.util.ListIterator;
import java.util.ArrayList;


public class CreateHashtable extends DepthFirstAdapter {

//	List hash;
	
	List lista_metodos;

	public CreateHashtable ()
	{
//		hash = new ArrayList();
		lista_metodos =  new ArrayList();
	}

	public List getHash ()
	{
		return lista_metodos;
	}

	public void showHash ()
	{
		if (lista_metodos != null)
		{
			for (int i=0; i < lista_metodos.size(); i++)
			{
				ListOfSymbols tmp = (ListOfSymbols) lista_metodos.get(i);

				System.out.println (tmp.getName());
				for (int j=0; j < tmp.symbols.size(); j++)
				{
					System.out.println (j + ": " + tmp.symbols.get(j));
				}
			}
		}
		else
			System.out.println ("hash nulo");

	}

	private void add_hash (String identificador, String method_name)
	{
		/*
		if(lista_metodos != null)			
		if (!lista_metodos.contains (identificador))
		{
			h.add (identificador);
		}*/

		boolean b = true;

		if(lista_metodos != null)			
		for (int i=0; i < lista_metodos.size() && b == true; i++)
		{
			ListOfSymbols los = (ListOfSymbols) lista_metodos.get (i);
			if (los.getName().equals (method_name))
			{
				if (!los.symbols.contains (identificador))
					los.symbols.add (identificador);
				b = false;
			}

		}
		if (b)
		{
			List tmp = new ArrayList();
			tmp.add (identificador);
			lista_metodos.add (new ListOfSymbols(method_name, tmp));
		}

		

	}

	private void procesar_bloque (Object b_test, String method_name)
	{
		AConsBloque bloque = null;

		if (b_test == null)
			return;

		if (b_test instanceof ANilBloque)
			return;

		if (b_test instanceof AConsBloque)
			bloque = (AConsBloque) b_test;
		else
			return;

		Object instruccion = bloque.getInstruccion();

		if(instruccion instanceof AAsignacionInstruccion)
		{
			AAsignacionInstruccion asignacioni = (AAsignacionInstruccion) instruccion;
			add_hash (asignacioni.getIdentificador().getText(), method_name);
		}
		

		if(instruccion instanceof ACicloInstruccion)
		{
			ACicloInstruccion cicloi = (ACicloInstruccion) instruccion;
			procesar_bloque (cicloi.getBloque(), method_name);
			//AProgramaPrograma n = new AProgramaPrograma ();
			//n.setBloque (cicloi.getBloque ());
			//caseAProgramaPrograma (n);

		}
		if(instruccion instanceof ACondicionalInstruccion)
		{
			ACondicionalInstruccion condicionali = (ACondicionalInstruccion) instruccion;
			//AProgramaPrograma n = new AProgramaPrograma ();
			//n.setBloque (condicionali.getBthen ());
			//caseAProgramaPrograma (n);
			
			//n.setBloque (condicionali.getBelse ());
			//caseAProgramaPrograma (n);

			procesar_bloque (condicionali.getBthen(), method_name);
			procesar_bloque (condicionali.getBelse(), method_name);

		}
		if(bloque.getBloque() instanceof AConsBloque)
		{
			//node.setBloque(bloque.getBloque());
			//caseAProgramaPrograma (node);
			procesar_bloque (bloque.getBloque(), method_name);
		}

	}	


	private void procesar_parametros (Object pparam, String method_name)
	{
		if(pparam instanceof AParamnParametros)
		{
			AParamnParametros parametro = (AParamnParametros) pparam;
			add_hash (parametro.getIdentificador().getText(), method_name);

			procesar_parametros(parametro.getParametros(), method_name);
		}


		if(pparam instanceof AParam1Parametros)
		{
			AParam1Parametros parametro = (AParam1Parametros) pparam;
			add_hash (parametro.getIdentificador().getText(), method_name);

		}

	}	

	public void caseAMetodoMetodo (AMetodoMetodo node)
	{
		//System.out.println ("metodo: " + node.getIdentificador().getText());

		if (node == null || !(node instanceof AMetodoMetodo))
			return;

		String identificador = node.getIdentificador().getText();
	
		//lista_metodos.add (new ListOfSymbols(identificador, ));

		Object param = node.getParametros();

		procesar_parametros (param, identificador);

		procesar_bloque (node.getBloque(), identificador);

		if(node.getMetodo() instanceof AMetodoMetodo)
		{
			caseAMetodoMetodo ((AMetodoMetodo)node.getMetodo());
		}
	}

	public void caseAProgramaPrograma (AProgramaPrograma node)
	{

		if (node == null)
			return;

		if (node.getMetodo() instanceof AMetodoMetodo)
			caseAMetodoMetodo ((AMetodoMetodo) node.getMetodo());

		Object b_test = node.getBloque();
		
		procesar_bloque (b_test, "main");



	}

} 
